import { omit } from "lodash";
import BaseNode from "./butterfly/node";
import BaseEdge from "./butterfly/edge";
import { buildInControl } from "./constants";
const separator = "__$__";
const omitKeys = ["id", "__butterfly", "next", "type"]
export function generatorButterflyData(graph: any, config: any = {}) {
  let nodes = [];
  let edges = [];
  Object.keys(graph).forEach(key => {
    const currentGraph = graph[key];
    let currentConfig = config[key] || buildInControl[key];
    currentGraph.id = key;
    if (!currentConfig) {
      buildInControl.handler?.[currentGraph.type]
        ? currentConfig = buildInControl.handler?.[currentGraph.type]
        : currentConfig = buildInControl.emitter?.[currentGraph.type]
    }
    if (!currentConfig) return;
    nodes.push({
      id: key,
      title: currentConfig.name,
      top: currentGraph.__butterfly?.top || 0,
      left: currentGraph.__butterfly?.left || 0,
      action: currentConfig.action,
      event: currentConfig.event,
      type: currentGraph.type,
      Class: BaseNode,
      ...omit(currentGraph, omitKeys)
    });
    switch (currentGraph.type) {
      case "node":
      case "condition":
        Object.keys(currentGraph).forEach(childKey => {
          currentGraph[childKey]?.next
            && (edges = [].concat(edges, createEdgeWithNextData(currentGraph[childKey]?.next, currentGraph)));
        })
        break;
      default:
        currentGraph.next && (edges = [].concat(edges, createEdgeWithNextData(currentGraph.next, currentGraph)));
        break;
    }
  });
  return { nodes, edges };
}


function createEdgeWithNextData(nextData, currentGraph) {
  return (nextData || []).map(nextItem => {
    let sourceEndpoint = `${currentGraph.id}${separator}${nextItem.eventName}`;
    let targetEndpoint = `${nextItem.id}${separator}${nextItem.actionName}`;
    return {
      type: "endpoint",
      source: sourceEndpoint,
      target: targetEndpoint,
      sourceNode: currentGraph.id,
      targetNode: nextItem.id,
      arrow: true,
      Class: BaseEdge
    }
  });
}
